|2010 DIM YA$(|12),YA%(|12,2),ZS9(|13,1),YT$(|35),YT%(|35,8),YR$(|35)
*23 |2015 DIM YH%(|02,|04),YE%(|02,|04) 'Keep track of first and last Detail record numbers
|2100 BLINKNORMAL%=|28:BLINKINSERT%=|29:BLINK2%=|30 'For CGA or EGA adapter, BLINKNORMAL%=6, BLINKINSERT%=4 and BLINK2%=7. For Monochrome adapter, BLINKNORMAL%=13, BLINKINSERT%=9 and BLINK2%=14.
2110 CLS:LOCATE 1,19,0:COLOR COLA%(2),COLA%(1)
2120 PRINT "PDS*BASE Data Base Mail Merge File Program";:COLOR 7,0
|2130 ZPASS=1:ZF$="|15":ZA=|16
2140 ON ERROR GOTO 2190
2150 LOCATE 3,19:COLOR COLA%(2),0:PRINT "Reading sort keys from file ";ZF$;:COLOR 7,0::OPEN ZF$ FOR INPUT AS ZQ+1:IF ZPASS=1 THEN INPUT #ZQ+1, ZTDATE$,ZTTIME$:INPUT #ZQ+1, Z5
|2160 IF ZPASS=1 THEN IF Z5<>ZS%(|16,6) THEN BEEP:LOCATE 4,2:COLOR 0,COLA%(4):PRINT "The number of records in the key file doesn't = Number of records in data base";:COLOR 7,0:CLOSE #ZQ+1:FOR X=1 TO 1000:NEXT:GOTO 2210
2170 IF ZPASS=1 THEN IF ZDATE$(ZA)<>ZTDATE$ OR ZTIME$(ZA)<>ZTTIME$ THEN BEEP:LOCATE 4,7:COLOR 0,COLA%(4):PRINT "Date & Time for the key file doesn't=Date & Time in the data base";:COLOR 7,0:CLOSE #ZQ+1:FOR X=1 TO 1000:NEXT:GOTO 2210
2180 ON ERROR GOTO 0:GOTO 2220
2190 RESUME 2200
*39 2200 IF ZPASS=2 THEN 2210 ELSE ZF$=CHR$(ZT%(ZA,1,3)+64)+":"+LEFT$(ZS$(ZA,1),(LEN(ZS$(ZA,1))-4))+".SRT":ZPASS=2:GOTO 2150
*40 2200 IF ZPASS=2 THEN 2210 ELSE ZF$=LEFT$(ZS$(ZA,1),(LEN(ZS$(ZA,1))-4))+".SRT":ZPASS=2:GOTO 2150
*41 2205 RESUME 2210
*42 2210 ON ERROR GOTO 0:CLOSE #ZQ+1:GOTO 2250
*41 2210 LOCATE 5,8:PRINT "The sort key file can not be used - Run the sort program again.":LOCATE 6,20,1:PRINT "Strike any key to end the program . . .":a$=input$(1):GOTO 400
*42 2220 ZZ5=0 'read the sort key file
*42 2230 WHILE NOT EOF(ZQ+1):ZZ5=ZZ5+1:INPUT #ZQ+1, YA%(ZZ5,2):WEND 'read the live record numbers
*42 2240 CLOSE #ZQ+1:IF ZZ5=ZS%(ZA,6) THEN IF ZPASS=1 THEN GOTO 2500 'the number of records in the sort key file may be larger if a master was deleted and re-created in the same dated session
*42 |2250 LOCATE 5,11:COLOR COLA%(2),0:PRINT "The data base must be re-sorted from the '";ZS$(|16,1);"' file.";:COLOR 7,0:Z5=0:ZA=|16
*42 2260 ZJJ=ZS%(ZA,2):IF ZPASS=2 AND ZZ5=ZS%(ZA,6) THEN ZJJ=ZZ5
*42 2270 FOR ZJ=1 TO ZJJ
*42 2280 IF ZZ5=ZS%(ZA,6) AND ZPASS=2 THEN ZR=YA%(ZJ,2) ELSE ZR=ZJ
*42 2290 ZZ=1:GOSUB 610
*42 |2300 IF ZL$<>STRING$(ZSIZE%(|16,|17),32) THEN Z5=Z5+1:YA$(Z5)=|22:YA%(Z5,1)=Z5:YA%(Z5,2)=ZR:LOCATE 6,25:PRINT ZR,ZL$;
*42 2310 NEXT 'ZJ
*42 |2320 ZREPTFLAG=0:IF Z5<> ZS%(|16,6) THEN ZS%(|16,6)=Z5:ZREPTFLAG=1 ' correct records assigned and set flags to correct the housekeeping record on closing the data base.
*42 2330 SOUND 400,1:LOCATE 7,20:COLOR COLA%(2),0:PRINT "There will be a file sort delay.";:COLOR 7,0:T%=INT((80-LEN(YA$(1)))/2)
2530 IF ESCFLAG%=1 OR F$=STRING$(20,32) THEN GOTO 400
2540 ON ERROR GOTO 2590:OPEN F$ FOR INPUT AS #ZQ+1:CLOSE ZQ+1
2550 ON ERROR GOTO 0:LOCATE 24,5,0:COLOR 15,0:BEEP:PRINT "File "+F$+" already exists. Do you wish to replace it ? ";:COLOR 0,COLA%(3):PRINT "N";:LOCATE ,POS(0)-1,1
2560 A$="":WHILE A$="":A$=INKEY$:WEND:IF ASC(A$)=13 THEN A$="N"
2570 PRINT A$;:COLOR 7,0:FOR J=1 TO 500:NEXT:LOCATE 24,1:PRINT SPC(79)
2580 IF A$<>"Y" AND A$<>"y" THEN GOTO 2500 ELSE GOTO 2600
2590 RESUME 2600
2600 OPEN F$ FOR OUTPUT AS #ZQ+1
|3110 FOR ZI=1 TO |35:FOR ZJ=1 TO 8:READ YT%(ZI,ZJ):NEXT:READ HEADER$(ZI),TRAILER$(ZI):NEXT ZI
3120 ' YT%(X,Y) X=Field on report, Y=1 is file number, 2=field in that file, 3=lead to file, 4=lead to field
3130 ' 5=Detail fld action code (1=1st Detail, 2=last, 3=all), 6=Associated Master if this is a Detail
3140 ' 7=Which Detail set for this Detail's Master, 8=1 If field starts new row
*44
3300 YL$="":ZA=0
3310 LOCATE 12,18,0:COLOR COLA%(2),COLB%(1):PRINT "Writing to disk file ";F$;:COLOR 7,0
3340 FOR ZI=1 TO Z5 'loop for each record in the sort file
3350 YF=0:MOREDETAIL%=0:YJ=1
|3360 FOR ZJ=YJ TO |35 'loop for each field in the Label
3370 IF ZJ=1 THEN ZZ=1:ZA=YT%(1,1):ZR=YA%(ZI,2):GOSUB 610:GOSUB 4000:GOTO 3420 'read the record for the first field
*47 3380 IF ZS%(YT%(ZJ,1),1)=2 GOTO 3440
3390 IF ZA=YT%(ZJ,1) THEN GOSUB 4000:GOTO 3570 'additional field in the same master
3400 IF ZA<>YT%(ZJ,1) AND ZS%(YT%(ZJ,1),1)=1 AND YR$(ZJ)=STRING$(YT%(ZJ,4),32) THEN GOTO 3580 'skip the new field if the field leading to it was blank
3410 IF ZA<>YT%(ZJ,1) AND ZS%(YT%(ZJ,1),1)=1 THEN ZA=YT%(ZJ,1):ZR$=YR$(ZJ):GOSUB 500:GOSUB 600:LSET YT$(ZJ)=Y$(YT%(ZJ,2),ZA) 'field in a different master
*47 3420 IF ZS%(ZA,4)>0 THEN FOR ZK=1 TO ZS%(ZA,4):YH%(ZA,ZK)=ZH(ZK):YE%(ZA,ZK)=ZE(ZK):NEXT 'ZK store the chain head and ends for this master record
*48 3420 REM continuation line - do not remove
*47 3430 GOTO 3540
*47 3440 'handle the detail record DO NOT remove this REM line
*47 3450 IF YT%(ZJ,1) = YT%(ZJ-1,1) THEN GOTO 3540
*47 3460 ZR=0:ZA=YT%(ZJ,1)
*47 3470 IF YF>0 THEN ZR=YF:GOTO 3500
*47 3480 IF YT%(ZJ,5)<>2 THEN ZR=YH%(YT%(ZJ,6),YT%(ZJ,7))
*47 3490 IF YT%(ZJ,5)=2 THEN ZR=YE%(YT%(ZJ,6),YT%(ZJ,7))
*47 3500 IF ZR>0 THEN ZZ=1:GOSUB 610 'read the 1st, last or next detail record
*47 3510 IF ZR=0 GOTO 3580
*47 3520 IF YT%(ZJ,5)=3 AND ZF>0 THEN MOREDETAIL%=1
*47 3530 IF MOREDETAIL%=1 THEN IF ZF>0 THEN YJ=ZJ:YF=ZF ELSE YF=0 'set up to read additional details
*47 3540 GOSUB 4000
|3550 FOR Z1=1 TO |35:IF ZA=YT%(Z1,3) THEN YR$(Z1)=Y$(YT%(Z1,4),ZA) 'set up future field search value
3560 NEXT 'Z1
3570 NEXT 'ZJ
3580 PRINT #ZQ+1, 'end of record
3600 IF YF>0 THEN GOTO 3360 'repeat for additional Details
3610 NEXT 'ZI
3620 CLOSE ZQ+1
3640 'all done"
3650 GOTO 400
4000 '***** Trim and Print Subroutine *****
4040 SKIP%=0:FLDLEN%=LEN(Y$(YT%(ZJ,2),ZA)):IF Y$(YT%(ZJ,2),ZA)=STRING$(FLDLEN%,32) THEN SKIP%=1:GOTO 4070 ELSE IF RIGHT$(Y$(YT%(ZJ,2),ZA),1)<>" " THEN GOTO 4070 ' field is full
4050 FOR K=FLDLEN% TO 1 STEP -1:IF MID$(Y$(YT%(ZJ,2),ZA),K,1)<>" " THEN FLDLEN%=K:K=1
4060 NEXT 'K
4070 IF ZJ>1 THEN PRINT #ZQ+1, ",";
4080 IF SKIP%=1 THEN PRINT #ZQ+1, CHR$(34)+CHR$(34);:RETURN 'two quote marks for empty field
5640 IF YC%=75 THEN ZJ=ZJ-1:IF ZJ>0 THEN ZJ=ZJ-1:LOCATE ,POS(0)-1:RETURN 'left arrow
5650 IF YC%=77 AND ZJ<Z2 THEN LOCATE ,POS(0)+1:RETURN 'right arrow
5710 IF YC%=82 THEN ZJ=ZJ-1:IF INSERT%=0 AND ZJ<Z2 THEN INSERT%=1:LOCATE ,,,BLINKINSERT%,BLINK2%:RETURN ELSE INSERT%=0:LOCATE ,,,BLINKNORMAL%,BLINK2%:RETURN ' insert key
5720 IF YC%=83 THEN IF ZJ<Z2 THEN FLD$=MID$(F$,ZJ+1)+" " ELSE FLD$=" " 'delete key
5730 IF YC%=83 THEN COLOR 0,COLA%(3):LOCATE ,,0:PRINT FLD$:COLOR 7,0:LOCATE FLDPOSVERT%,POSY%,1:MID$(F$,ZJ)=FLD$:ZJ=ZJ-1:RETURN 'delete key
5740 SOUND 400,1:RETURN 'key not used
5800 'Character type field
5810 IF YC%>96 AND YC%<123 THEN YC%=YC%-32:YC$=CHR$(YC%):RETURN ELSE IF YC%>44 OR YC%<91 THEN RETURN